package com.sjb.sixteen_journey_backend.handler.exception;

import com.aliyun.oss.ServiceException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.sjb.sixteen_journey_backend.common.R;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.RedisConnectionFailureException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartException;

import java.util.stream.Collectors;

@ControllerAdvice  //这个注解表示这个类是全局异常处理类
@ResponseBody
@Slf4j
public class GlobalExceptionHandler {


    @ResponseBody // 将方法的返回值作为响应体返回
    @ExceptionHandler(MethodArgumentNotValidException.class) //获所有因数据验证失败而抛出的异常
    @ResponseStatus(HttpStatus.BAD_REQUEST) // 设置响应状态码为400 Bad Request
    public R handleMethodArgumentNotValidException(MethodArgumentNotValidException ex, HttpServletRequest request) {

        BindingResult bindingResult = ex.getBindingResult();
        if (bindingResult.hasErrors()) {
            // 收集所有错误信息
            String errorMessage = bindingResult.getFieldErrors().stream()
                    .map(FieldError::getDefaultMessage)
                    .collect(Collectors.joining("; "));

            // 返回包含所有错误信息的响应
            return R.error(errorMessage, 400);
        }
        return R.error("验证失败", 400);
    }



    @ExceptionHandler(value = {Exception.class})
    public <T> R<T> exceptionHandler(Exception e){
        //如果拦截到的是自定义异常,则自己处理
        if(e instanceof CustomException){
            CustomException customException = (CustomException) e;//强转为自定义异常
            //返回自定义异常
            return R.error(customException.getMsg(),customException.getCode());
        }else if(e instanceof RedisConnectionFailureException){
            return R.error(CustomExceptionCodeMsg.UNABLE_TO_CONNECT_TO_REDIS.getMsg(),CustomExceptionCodeMsg.UNABLE_TO_CONNECT_TO_REDIS.getCode());
        }
        log.error("【非自定义异常】↓↓↓",e);
        //不是自定义异常,且未知,则统一返回500
        return R.error(CustomExceptionCodeMsg.SERVER_ERROR.getMsg(),CustomExceptionCodeMsg.SERVER_ERROR.getCode());
    }

    @ExceptionHandler(JWTVerificationException.class)
    @ResponseBody
    public R tokenExpiredException(JWTVerificationException e) {
        //e.printStackTrace();
        return R.error("Token已过期", 401);
    }

//    @ExceptionHandler(RuntimeException.class)
//    @ResponseBody
//    public R RunTimeExpiredException(RuntimeException e) {
//        log.error("【RuntimeException异常】↓↓↓",e);
//        return R.error(CustomExceptionCodeMsg.SERVER_ERROR.getMsg(),CustomExceptionCodeMsg.SERVER_ERROR.getCode());
//    }

    @ExceptionHandler(MultipartException.class)
    @ResponseBody
    public R handleMultipartException(MultipartException e) {
        return R.error(CustomExceptionCodeMsg.MAXIMUN_UPLOAD_SIZE.getMsg(),CustomExceptionCodeMsg.MAXIMUN_UPLOAD_SIZE.getCode());
    }

}
